package edu.cicese.alz;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 28/11/11
 * Time: 12:33 PM
 */

import edu.cicese.alz.reports.AccelerometerMeasure;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYAreaRenderer2;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;

import java.awt.Color;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;

/**
 * A demo showing a time series with per minute data.
 *
 * @author David Gilbert
 */
public class PlotData extends ApplicationFrame {

	private int scale = 1;
	private TimeSeriesCollection[] collectionsAccelerometer;
	private TimeSeriesCollection collectionAccelerometerSummary;
	private XYDataset collectionsActivity;
	private XYDataset collectionsGPS;
	private ArrayList<Color> activityColors = new ArrayList<>();

	private boolean saveToFile = false;

	private double dataType1Min = 9.25, dataType1Max = 10.4;
	private long tsAllowedWindow = 40000, tsMovementWindow = 10000;

	/**
     * A demonstration application.
     *
     * @param title  the frame title.
	 * @param resultSetAccelerometer a
	 * @param resultSetActivity b
	 */
    public PlotData(String title, ResultSet resultSetAccelerometer, ResultSet resultSetActivity) {
	    super(title);

	    collectionsAccelerometer = createAccelerometerSeries(getAccelerometerData(resultSetAccelerometer));
	    collectionsActivity = createActivitySeries(getActivityData(resultSetActivity));
        JFreeChart chart = createCombinedChart();

//	    ChartPanel chartPanel = new ChartPanel(chart);
        ChartPanel chartPanel = new ChartPanel(chart, true, true, true, false, true);
        chartPanel.setPreferredSize(new java.awt.Dimension(1000, 500));
        setContentPane(chartPanel);





        /*TimeSeriesCollection dataset = new TimeSeriesCollection(createAccelerometerSeries(getAccelerometerData(resultSet1)));
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Time Series DemoJMap 10",
            "Tiempo",
            "Magnitud",
            dataset,
            true,
            true,
            false
        );*/

/*		XYPlot plot = chart.getXYPlot();
        plot.setInsets(new RectangleInsets(0, 0, 0, 20));
        Marker marker = new ValueMarker(700.0);
        marker.setPaint(Color.blue);
        marker.setAlpha(0.8f);
        plot.addRangeMarker(marker);
//        plot.setBackgroundPaint(null);
//        plot.setBackgroundImage(JFreeChart.INFO.getLogo());
        XYItemRenderer renderer = plot.getRenderer();
            XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) renderer;
	        r.setDrawSeriesLineAsPath(false);
	        r.setBaseShapesFilled(true);
	    r.setDataBoundsIncludesVisibleSeriesOnly(false);*/

//        ChartPanel chartPanel = new ChartPanel(chart);
//        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
//        chartPanel.setMouseZoomable(true, true);
//        setContentPane(chartPanel);


//        ChartPanel chartPanel = new ChartPanel(chart);
//        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
//        setContentPane(chartPanel);

    }

	public PlotData(String title, ResultSet resultSetAccelerometer, ResultSet resultSetActivity, boolean summary,
	                boolean saveToFile) {
	    super(title);

		this.saveToFile = saveToFile;

		JFreeChart chart;

		if (!summary) {
			collectionsAccelerometer = createAccelerometerSeries(getAccelerometerData(resultSetAccelerometer));
			collectionsActivity = createActivitySeries(getActivityData(resultSetActivity));
			chart = createCombinedChart();
		}

		else {
			collectionAccelerometerSummary = createAccelerometerSummarySeries(getAccelerometerSummary(resultSetAccelerometer));
			collectionsActivity = createActivitySeries(getActivityData(resultSetActivity));
			chart = createCombinedSummaryChart();
		}

		ChartPanel chartPanel = new ChartPanel(chart, true, true, true, false, true);
		chartPanel.setPreferredSize(new java.awt.Dimension(1000, 500));
		setContentPane(chartPanel);
    }

	public PlotData(String title, ResultSet resultSetActivity) {
		super(title);
	    collectionsActivity = createActivitySeries(getActivityData(resultSetActivity));
        JFreeChart chart = createNFCChart();

        ChartPanel chartPanel = new ChartPanel(chart, true, true, true, false, true);
        chartPanel.setPreferredSize(new java.awt.Dimension(1000, 500));
        setContentPane(chartPanel);
	}

//	public PlotData(String title, ResultSet resultSetGPS, boolean GPS) {
//		super(title);
//	    collectionsActivity = createGPSSeries(resultSetGPS);
//        JFreeChart chart = createNFCChart();
//
//        ChartPanel chartPanel = new ChartPanel(chart, true, true, true, false, true);
//        chartPanel.setPreferredSize(new java.awt.Dimension(1000, 500));
//        setContentPane(chartPanel);
//	}

	public PlotData(String title, ArrayList<ActivityMeasure> activityMeasures) {
		super(title);
	    collectionsActivity = createActivitySeries(getActivityData(activityMeasures));
        JFreeChart chart = createNFCChart();

        ChartPanel chartPanel = new ChartPanel(chart, true, true, true, false, true);
        chartPanel.setPreferredSize(new java.awt.Dimension(1000, 500));
        setContentPane(chartPanel);
	}


	private JFreeChart createNFCChart() {
		XYAreaRenderer2 renderer5 = new XYAreaRenderer2();
		setRendererColors(renderer5);
        NumberAxis rangeAxis5 = new NumberAxis("Activities");
		XYPlot subplot5 = new XYPlot(collectionsActivity, new DateAxis(), rangeAxis5, renderer5);

		CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new DateAxis("Date"));
		plot.add(subplot5, 2);
        plot.setOrientation(PlotOrientation.VERTICAL);

        // return a new chart containing the overlaid plot...
        return new JFreeChart("NFC Chart",
                              JFreeChart.DEFAULT_TITLE_FONT, plot, true);
	}

	private JFreeChart createCombinedChart() {


        // create subplot 1...
        XYDataset dataAxisX = collectionsAccelerometer[0];
        XYItemRenderer renderer1 = new StandardXYItemRenderer();
        NumberAxis rangeAxis1 = new NumberAxis("Axis X");
        XYPlot subplot1 = new XYPlot(dataAxisX, new DateAxis(), rangeAxis1, renderer1);
        subplot1.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
		StandardXYItemRenderer r = (StandardXYItemRenderer) subplot1.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);

//        XYTextAnnotation annotation = new XYTextAnnotation("Hello!", 50.0, 10000.0);
//        annotation.setFont(new Font("SansSerif", Font.PLAIN, 9));
//        annotation.setRotationAngle(Math.PI / 4.0);
//        subplot1.addAnnotation(annotation);

        // create subplot 2...
        XYDataset dataAxisY = collectionsAccelerometer[1];
	    XYItemRenderer renderer2 = new StandardXYItemRenderer();
        NumberAxis rangeAxis2 = new NumberAxis("Axis Y");
//        rangeAxis2.setAutoRangeIncludesZero(false);
        XYPlot subplot2 = new XYPlot(dataAxisY, new DateAxis(), rangeAxis2, renderer2);
        subplot2.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
		r = (StandardXYItemRenderer) subplot2.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);

		// create subplot 3...
        XYDataset dataAxisZ = collectionsAccelerometer[2];
	    XYItemRenderer renderer3 = new StandardXYItemRenderer();
        NumberAxis rangeAxis3 = new NumberAxis("Axis Z");
//        rangeAxis3.setAutoRangeIncludesZero(false);
        XYPlot subplot3 = new XYPlot(dataAxisZ, new DateAxis(), rangeAxis3, renderer3);
        subplot3.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
		r = (StandardXYItemRenderer) subplot3.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);

		// create subplot 4...
        /*XYDataset dataMagnitude = collections[3];
	    XYItemRenderer renderer4 = new StandardXYItemRenderer();
        NumberAxis rangeAxis4 = new NumberAxis("Magnitude");
//        rangeAxis4.setAutoRangeIncludesZero(false);
        XYPlot subplot4 = new XYPlot(dataMagnitude, new DateAxis(), rangeAxis4, renderer4);
        subplot4.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
		r = (StandardXYItemRenderer) subplot4.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);*/

		XYDataset dataMagnitude = collectionsAccelerometer[3];


	    XYItemRenderer renderer4 = new StandardXYItemRenderer();
        NumberAxis rangeAxis4 = new NumberAxis("Magnitude");
//        rangeAxis4.setAutoRangeIncludesZero(false);
        XYPlot subplot4 = new XYPlot(dataMagnitude, new DateAxis(), rangeAxis4, renderer4);

//		subplot4.setRangeAxis(1, rangeAxis4);
//		subplot4.setDataset(1, dataActivities);
//		subplot4.setRenderer(1, renderer4);

        subplot4.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
		r = (StandardXYItemRenderer) subplot4.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);


//		XYDataset dataActivities = createActivitySeries();
		XYAreaRenderer2 renderer5 = new XYAreaRenderer2();
		setRendererColors(renderer5);
        NumberAxis rangeAxis5 = new NumberAxis("Activities");
		XYPlot subplot5 = new XYPlot(collectionsActivity, new DateAxis(), rangeAxis5, renderer5);
//		subplot5.setForegroundAlpha(0.5f);


//		JFreeChart chart = ChartFactory.createXYAreaChart(
//				"XY Area Chart DemoJMap 2",
//				"Time", "Value",
//				null,
//				PlotOrientation.VERTICAL,
//				true,  // legend
//				true,  // tool tips
//				false  // URLs
//		);

		

//		DateAxis dateaxis = new DateAxis("Date");
//        dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
//        NumberAxis numberaxis = new NumberAxis("Value");

//        IntervalXYDataset intervalxydataset = createDataset1();
//        XYBarRenderer xybarrenderer = new XYBarRenderer(0.20000000000000001D);
//        xybarrenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator("{0}: ({1}, {2})", new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00")));
//
//		XYPlot xyplot = new XYPlot(intervalxydataset, dateaxis, numberaxis, xybarrenderer);
//        NumberAxis numberaxis1 = new NumberAxis("Value 2");
//        xyplot.setRangeAxis(1, numberaxis1);

//        XYDataset xydataset = createDataset2A();
//        StandardXYItemRenderer standardxyitemrenderer = new StandardXYItemRenderer();
//        standardxyitemrenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator("{0}: ({1}, {2})", new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00")));
//        xyplot.setDataset(1, xydataset);
//        xyplot.setRenderer(1, standardxyitemrenderer);


        // parent plot...
        CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new DateAxis("Date"));
        plot.setGap(10.0);


        // add the subplots...
//        plot.add(subplot1, 1);
//        plot.add(subplot2, 1);
//		plot.add(subplot3, 1);
		plot.add(subplot4, 2);
		plot.add(subplot5, 2);
        plot.setOrientation(PlotOrientation.VERTICAL);

        // return a new chart containing the overlaid plot...
        return new JFreeChart("Accelerometer and NFC Chart",
                              JFreeChart.DEFAULT_TITLE_FONT, plot, true);

    }

	private JFreeChart createCombinedSummaryChart() {
		XYDataset dataMagnitude = collectionAccelerometerSummary;
	    XYItemRenderer renderer1 = new StandardXYItemRenderer();
        NumberAxis rangeAxis1 = new NumberAxis("Data");
		rangeAxis1.setAutoRangeMinimumSize(3);
        XYPlot subplotAccSum = new XYPlot(dataMagnitude, new DateAxis(), rangeAxis1, renderer1);
        subplotAccSum.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);

		StandardXYItemRenderer r = (StandardXYItemRenderer) subplotAccSum.getRenderer();
		r.setDataBoundsIncludesVisibleSeriesOnly(false);


//		XYDataset dataActivities = createActivitySeries();
		XYAreaRenderer2 renderer2 = new XYAreaRenderer2();
		setRendererColors(renderer2);
        NumberAxis rangeAxis2 = new NumberAxis("Activities");
		XYPlot subplotNFC = new XYPlot(collectionsActivity, new DateAxis(), rangeAxis2, renderer2);

        // parent plot...
        CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new DateAxis("Date"));
        plot.setGap(10.0);


        // add the subplots...
		plot.add(subplotAccSum, 2);
		plot.add(subplotNFC, 2);
        plot.setOrientation(PlotOrientation.VERTICAL);

        // return a new chart containing the overlaid plot...
        return new JFreeChart("Accelerometer and NFC Summary Chart",
                              JFreeChart.DEFAULT_TITLE_FONT, plot, true);

    }

	private void setRendererColors(XYAreaRenderer2 renderer) {
		for (int i = 0; i < activityColors.size(); i++) {
			renderer.setSeriesPaint(i, activityColors.get(i));
		}
	}

	
	// ACCELEROMETER
	public TimeSeriesCollection[] createAccelerometerSeries(ArrayList<AccelerometerMeasure> accelerometerMeasures) {
		TimeSeriesCollection[] collections = new TimeSeriesCollection[4];
		TimeSeries seriesAxisX = new TimeSeries("Axis X");
		TimeSeries seriesAxisY = new TimeSeries("Axis Y");
		TimeSeries seriesAxisZ = new TimeSeries("Axis Z");
		TimeSeries seriesMagnitude = new TimeSeries("Magnitudes");
		Millisecond millisecond;
		for (AccelerometerMeasure measure : accelerometerMeasures) {
			millisecond = getMillisecond(measure.getTimestamp());
			seriesAxisX.addOrUpdate(millisecond, measure.getAxisX());
			seriesAxisY.addOrUpdate(millisecond, measure.getAxisY());
			seriesAxisZ.addOrUpdate(millisecond, measure.getAxisZ());
			seriesMagnitude.addOrUpdate(millisecond, measure.getMagnitude());
		}

		collections[0] = new TimeSeriesCollection(seriesAxisX);
		collections[1] = new TimeSeriesCollection(seriesAxisY);
		collections[2] = new TimeSeriesCollection(seriesAxisZ);
		collections[3] = new TimeSeriesCollection(seriesMagnitude);

		return collections;
	}

    @SuppressWarnings({"unchecked"})
	public ArrayList<AccelerometerMeasure> getAccelerometerData(ResultSet resultSet) {
	    ArrayList<AccelerometerMeasure> accelerometerMeasures = new ArrayList<>();

	    double axisX, axisY, axisZ, magnitude;
	    long timestamp;

	    String accData = "timestamp,axisX,axisY,axisZ\n";
	    String folder = "D:\\_proyectoAlz\\analysis\\accelerometer\\";
	    String file = "accLog" + System.currentTimeMillis() + ".csv";
	    if (saveToFile) {
		    new File(folder).mkdirs();
		    saveDataFile(folder + file, accData);
	    }

	    try {
			while (resultSet.next()) {
				axisX = resultSet.getDouble(1);
				axisY = resultSet.getDouble(2);
				axisZ = resultSet.getDouble(3);
				magnitude = Math.sqrt(
								Math.pow(axisX, 2) +
								Math.pow(axisY, 2) +
								Math.pow(axisZ, 2));
				timestamp = resultSet.getLong(4);
				accelerometerMeasures.add(new AccelerometerMeasure(axisX, axisY, axisZ, magnitude, timestamp));
				if (saveToFile) {
					accData = timestamp + "," + axisX + "," + axisY + "," + axisZ + "\n";
					saveDataFile(folder + file, accData);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	    return accelerometerMeasures;
	}

	// ACCELEROMETER SUMMARY
	public ArrayList<AccelerometerMeasure> getAccelerometerSummary(ResultSet resultSet) {
		ArrayList<AccelerometerMeasure> magnitudes = new ArrayList<>();
		double magnitude;
		long timestamp;
		try {
			while (resultSet.next()) {
				magnitude = Math.sqrt(
								Math.pow(resultSet.getDouble(1), 2) +
								Math.pow(resultSet.getDouble(2), 2) +
								Math.pow(resultSet.getDouble(3), 2));
				timestamp = resultSet.getLong(4);
				magnitudes.add(new AccelerometerMeasure(getDataType(magnitude), timestamp));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		ArrayList<AccelerometerMeasure> accelerometerMeasures = new ArrayList<>();
		int dataTypeAux = magnitudes.get(0).getDataType();
		long timestampAux = magnitudes.get(0).getTimestamp();
		accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestampAux));
		magnitudes.remove(0);
		int dataType;

		boolean moving = dataTypeAux == 2;
		long timestampLastMovement = moving ? timestampAux : 0;
		boolean movedTwice = false;
		ArrayList<AccelerometerMeasure> tmpMeasures = new ArrayList<>();


		for (AccelerometerMeasure measure : magnitudes) {
			dataType = measure.getDataType();
			timestamp = measure.getTimestamp();

			if (moving) {
				if (timestamp - timestampLastMovement < tsMovementWindow) {
					if (dataType == 2) {
//						accelerometerMeasures.add(new AccelerometerMeasure(2, timestampLastMovement));
						tmpMeasures.clear();
						movedTwice = true;
						timestampLastMovement = timestamp;
					}
					else {
						tmpMeasures.add(new AccelerometerMeasure(dataType, timestamp));
					}
				}
				else {
					if (movedTwice) {
						accelerometerMeasures.add(new AccelerometerMeasure(2, timestampLastMovement));
					}
					else {
						// remove unique movement measure
						accelerometerMeasures.remove(accelerometerMeasures.size() - 1);
					}

					accelerometerMeasures.add(new AccelerometerMeasure(1, timestampLastMovement + 1));

					// add temp
					for (AccelerometerMeasure tmpMeasure : tmpMeasures) {
						dataType = tmpMeasure.getDataType();
						timestamp = tmpMeasure.getTimestamp();
						if (dataType != dataTypeAux) {
							if (dataTypeAux != 2) {
								accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestamp - 1));
							}
							accelerometerMeasures.add(new AccelerometerMeasure(dataType, timestamp));
							dataTypeAux = dataType;
						}
					}
					tmpMeasures.clear();
					movedTwice = false;
					moving = false;

					timestampAux = timestamp;
				}
			}
			else {
				if (dataType == 2) {
					accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestamp - 1));
					moving = true;
					timestampLastMovement = timestamp;
					accelerometerMeasures.add(new AccelerometerMeasure(2, timestamp));
//					tmpMeasures.add(new AccelerometerMeasure(2, timestamp));
				}
				else {
					if (timestamp - timestampAux > tsAllowedWindow) {
						accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestampAux));
						dataTypeAux = 0;
						accelerometerMeasures.add(new AccelerometerMeasure(0, timestampAux + 1));
					}

					if (dataType != dataTypeAux) {
						accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestamp - 1));
						accelerometerMeasures.add(new AccelerometerMeasure(dataType, timestamp));
						dataTypeAux = dataType;
					}
				}
				timestampAux = timestamp;
			}

		}




		/*long timestamp, timestampAux = 0, timestampLastMovement = 0;
		int dataType, dataTypeAux = 1;
		boolean moving = false;
		boolean movedTwice = false;
		ArrayList<AccelerometerMeasure> movingMeasures = new ArrayList<>();
		try {
			while (resultSet.next()) {
				axisX = resultSet.getDouble(1);
				axisY = resultSet.getDouble(2);
				axisZ = resultSet.getDouble(3);
				magnitude = Math.sqrt(
								Math.pow(axisX, 2) +
								Math.pow(axisY, 2) +
								Math.pow(axisZ, 2));
				timestamp = resultSet.getLong(4);

				// Get data type: Null | No Movement | Movement
				dataType = getDataType(magnitude);

				if (moving) {
					if (timestampLastMovement != 0 && timestamp - timestampLastMovement < tsMovementWindow) {
						// if the user moves again
						if (dataType == 2) {
							movedTwice = true;
							movingMeasures.clear();
							accelerometerMeasures.add(new AccelerometerMeasure(2, timestampLastMovement));
							accelerometerMeasures.add(new AccelerometerMeasure(2, timestamp));
							timestampLastMovement = timestamp;
						}
						else {
							movingMeasures.add(new AccelerometerMeasure(dataType, timestamp));
						}
					}
					// outside the movement window
					else {
						if (!movedTwice) {
//							accelerometerMeasures.addAll(movingMeasures);
						}
//						else {
//
//						}
					}
				}

				else {
					if (dataType == 2) {
						moving = true;
						timestampLastMovement = timestamp;
					}

					else {
						if (timestampAux != 0 && timestamp - timestampAux > tsAllowedWindow) {
							dataTypeAux = 0;
							accelerometerMeasures.add(new AccelerometerMeasure(0, timestampAux + 1));
//	        				accelerometerMeasures.add(new AccelerometerMeasure(0, timestamp - 1));
						}

						if (dataType != dataTypeAux) {
							accelerometerMeasures.add(new AccelerometerMeasure(dataTypeAux, timestamp - 1));
							dataTypeAux = dataType;
						}
						accelerometerMeasures.add(new AccelerometerMeasure(dataType, timestamp));
					}
				}

				timestampAux = timestamp;


			}
		} catch (SQLException e) {
			e.printStackTrace();
		}*/
	    return accelerometerMeasures;
	}

	public TimeSeriesCollection createAccelerometerSummarySeries(ArrayList<AccelerometerMeasure> accelerometerMeasures) {
		TimeSeriesCollection[] collections = new TimeSeriesCollection[4];
		TimeSeries seriesType = new TimeSeries("Data");
		Millisecond millisecond;
		for (AccelerometerMeasure measure : accelerometerMeasures) {
			millisecond = getMillisecond(measure.getTimestamp());
			seriesType.addOrUpdate(millisecond, measure.getDataType());
		}

		return new TimeSeriesCollection(seriesType);
	}

	public int getDataType(double magnitude) {
		if (magnitude > dataType1Min && magnitude < dataType1Max) {
			return 1;
		}
		else {
			return 2;
		}
	}


	// NFC
	private XYDataset createActivitySeries(ArrayList<ArrayList<ActivityMeasure>> activities) {
		TimeSeriesCollection activityCollections = new TimeSeriesCollection();
		long timestamp, timestampDiff;
		long width;
		double height;
		for (int i = 0; i < 25; i++) {
			height = 10d - (i + 1) * 1d / 3;
			ArrayList<ActivityMeasure> activityMeasures = activities.get(i);
			int activitySize = activityMeasures.size();
			if (activitySize > 0) {
				TimeSeries seriesActivity = new TimeSeries(activityMeasures.get(0).getMessage());
				for (int x = 0; x < activitySize; x++) {
					timestamp = activityMeasures.get(x).getTimestamp();
					if (x > 0) {
						seriesActivity.add(getMillisecond(timestamp - 1), 0d);
					}
					seriesActivity.add(getMillisecond(timestamp), height);
					// Set bar width (depends on the next activity's timestamp)
					width = 20000;
					if (x < activitySize - 1) {
						timestampDiff = activityMeasures.get(x + 1).getTimestamp() - timestamp;
						if (timestampDiff < 20003) {
							width = timestampDiff - 3;
						}
//						else {
//							width = 10000;
//						}
					}
//					else {
//						width = 10000;
//					}
					seriesActivity.add(getMillisecond(timestamp + width), height);
					seriesActivity.add(getMillisecond(timestamp + width + 1), 0d);
				}
				activityCollections.addSeries(seriesActivity);
				activityColors.add(NFCActivity.activityColors[i]);
			}
		}
//		for (ActivityMeasure measure : activities) {
//			TimeSeries seriesActivity = new TimeSeries(measure.getMessage());
//			seriesActivity.add(getMillisecond(measure.getTimestamp()), 10d);
//			seriesActivity.add(getMillisecond(measure.getTimestamp() + 4000), 10d);
//			seriesActivity.add(getMillisecond(measure.getTimestamp() + 4001), 0d);
//			seriesActivity.add(getMillisecond(measure.getTimestamp() + 8000), 0d);
//			seriesActivity.add(getMillisecond(measure.getTimestamp() + 8001), 10d);
//			seriesActivity.add(getMillisecond(measure.getTimestamp() + 12000), 10d);
//			activityCollections.addSeries(seriesActivity);
//		}

		
//	    TimeSeries seriesActivity = new TimeSeries("Activities");
//        seriesActivity.add(getMillisecond(1321527003458l), 3D);
//        seriesActivity.add(getMillisecond(1321527051241l), 5D);
//        seriesActivity.add(getMillisecond(1321565462916l), 3.5D);
//        seriesActivity.add(getMillisecond(1321580759556l), 1D);
//	    TimeSeries seriesActivity2 = new TimeSeries("Activities2");
//		seriesActivity2.add(getMillisecond(1321527003458l), 5D);
//        seriesActivity2.add(getMillisecond(1321527051241l), 10D);
//        seriesActivity2.add(getMillisecond(1321565462916l), 5D);
//        seriesActivity2.add(getMillisecond(1321580759556l), 7D);
//        TimeSeriesCollection activityCollections = new TimeSeriesCollection();
//        activityCollections.addSeries(seriesActivity);
//        activityCollections.addSeries(seriesActivity2);
		return activityCollections;
	}

	@SuppressWarnings({"unchecked"})
	public ArrayList<ArrayList<ActivityMeasure>> getActivityData(ResultSet resultSet) {
		ArrayList<ArrayList<ActivityMeasure>> activities = new ArrayList<>();
		for (int i = 0; i < 25; i++) {
			activities.add(new ArrayList<ActivityMeasure>());
		}

		int messageID;
//		int c = 0;
		try {
			while (resultSet.next()) {
//				c++;
				messageID = resultSet.getInt(2);
				activities.get(messageID - 1).add(new ActivityMeasure(messageID + ":" + resultSet.getString(1), resultSet.getLong(3)));
			}
//			System.out.println(c);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return activities;
	}

	public ArrayList<ArrayList<ActivityMeasure>> getActivityData(ArrayList<ActivityMeasure> activityMeasures) {
		ArrayList<ArrayList<ActivityMeasure>> activities = new ArrayList<>();
		for (int i = 0; i < 25; i++) {
			activities.add(new ArrayList<ActivityMeasure>());
		}

		for (ActivityMeasure activityMeasure : activityMeasures) {
			activities.get(activityMeasure.getMessageID() - 1).add(activityMeasure);
		}


		/*int messageID;
		try {
			while (resultSet.next()) {
				messageID = resultSet.getInt(2);
				activities.get(messageID - 1).add(new ActivityMeasure(messageID + ":" + resultSet.getString(1), resultSet.getLong(3)));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}*/

		return activities;
	}


	// UTILS
	public Millisecond getMillisecond(long timestamp) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(timestamp);
		return new Millisecond(cal.get(Calendar.MILLISECOND), cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE),
				cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH) + 1,
				cal.get(Calendar.YEAR));
	}

	private void saveDataFile(String filename, String row) {
		try {
			PrintWriter pw = new PrintWriter(new FileWriter(filename, true));
			pw.print(row);
			pw.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
